\subsection{Gestion des \textit{mutex} et des sémaphores}

\paragraph{Présentation}
Les \textit{mutex} et les sémaphores permettent à plusieurs \textit{threads} s'exécutant simultanément de partager des données sans aboutir à des incohérences. Ils permettent en particulier de restreindre les accès à une même donnée en même temps. Dans le cadre de notre projet, ils ne sont intéressants que si la préemption est implémentée, puisque ce n'est que si un \textit{thread} peut passer la main à un autre qu'il est possible d'avoir un accès concurrent à une même donnée. Puisque nous sommes parvenus à réaliser la gestion de la préemption, nous avons voulu implémenter cette fonctionnalité.

\paragraph{Implémentation des \textit{mutex} (\textsf{mutex[2].h/c})}
Nous avons fait le choix de dissimuler l'implémentation des \textit{mutex} à l'utilisateur. Ainsi nous définissons le type \verb+thread_mutex_t+, qui est en fait une structure ne contenant qu'un entier représentant le verrou et une liste de \textit{threads} pour l'attente passive. De cette façon nous pourrons modifier l'implémentation sans conséquence pour l'utilisateur.

Le fonctionnement d'un \textit{mutex} se résume à deux utilisations : le verrouiller et le déverrouiller. Lorsqu'il est verrouillé, les accès concurrents sont mis en attente. Lorsqu'il est déverrouillé, un \textit{thread} peut le verrouiller. Ces utilisations sont offertes par les fonctions \verb+thread_mutex_lock()+ et \verb+thread_mutex_unlock()+ prenant en paramètre un pointeur sur un \verb+thread_mutex_t+. Afin d'éviter les incohérences lors de la prise ou le relâchement du verrou, il est nécessaire que les opérations soient atomiques. Nous utilisons pour cela les fonctions que propose \textsf{gcc} et qui garantissent cette atomicité.

\medskip

Nous avons fait le choix de réaliser à la fois les \textit{mutex} à attente active (\textsf{mutex.h/c}) et à attente passive (\textsf{mutex2.h/c}).

Pour l'attente active, lorsqu'un \textit{mutex} est verrouillé, l'attente s'effectue grâce à une boucle \textsf{while}. Cette implémentation a pour avantage d'être simple et très rapide. Elle réclame néanmoins beaucoup de ressources. Ces \textit{mutex} doivent donc être utilisés pour des attentes très courtes. Un autre avantage est qu'il est possible d'utiliser nos \textit{mutex} avec n'importe quelle implémentation de \textit{thread}.

L'implémentation de \textsf{mutex} à attente passive est plus complexe. En contrepartie de la perte de leur universalité, ils réclament moins de ressources et peuvent donc être utilisés pour de longues attentes. Si le \textit{mutex} est déjà verrouillé, le \textit{thread} est ajouté dans la liste des \textit{threads} en attente (dans la structure), il est endormi et \verb+thread_next()+ est appelé. Lorsqu'un \textit{mutex} est déverrouillé, un des \textit{threads} en attente est réveillé et \verb+thread_next()+ est appelé.

\medskip

Les fonctions \verb+thread_mutex_init()+ et \verb+thread_mutex_destroy()+ permettent respectivement d'allouer la mémoire de la structure et de la liste et de la libérer.

\paragraph{Implémentation des sémaphores (\textsf{sem[2].h/c})}

Les sémaphores sont une généralisation des \textit{mutex}. La différence réside dans le fait qu'il autorise plusieurs accès concurrents en même temps à une même donnée, mais en nombre limité.

\medskip

Leur implémentation diffère donc peu des \textit{mutex}. De même, deux versions sont présentées : une à attente active et une à attente passive. La différence réside dans la valeur du sémaphore, que l'on peut d'ailleurs connaître grâce à la fonction \verb+thread_sem_getvalue()+.

\paragraph{Tests}

Quatre tests ont été réalisés : deux pour les \textit{mutex}, deux pour les sémaphores. Un des deux tests est à attente active, l'autre à attente passive. Il sont numérotés 71, 72, 73 et 74.

Le test des \textit{mutex} consiste à modifier les valeurs contenues dans un tableau. Deux \textit{threads} veulent le faire en même temps. Même si nous avons implémenté la préemption, nous voulons être sûr de passer la main à l'autre \textit{thread}. À chaque fois qu'un caractère est écrit, nous appelons donc la fonction \verb+thread_yield()+.

Le test des sémaphores consiste pour 4 \textit{threads} à lire plusieurs fois un même tableau en même temps. Nous voulons que seulement deux à la fois le lisent. Les \textit{threads} lisent le tableau un nombre de fois différent, afin de bien observer la prise du sémaphore entre les \textit{threads}. De même, à chaque fois qu'un caractère est lu, \verb+thread_yield()+ est appelé.